<template>
    <a-control-group class="a-input-number">
        <a-input-string class="c-w-100" :type="'number'" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :clearable="props.clearable" :isInner="true" @update:value="methods.onInput" :value="displayText" :placeholder="props.placeholder" :autoFocus="props.autoFocus" @focus="emit('focus')" @blur="$emit('blur')"></a-input-string>
        <template v-if="props.attachButtonShown">
            <a-control-group direction="v" class="c-f-shrink-0">
                <a-button class="action c-f-shrink-0" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :square="true" :halfHeight="true" @click="methods.add"><span class="fa fa-fw fa-caret-up"></span></a-button>
                <a-button class="action c-f-shrink-0" :color="formItemHook.myColor" :size="formItemHook.mySize" :sharp="formItemHook.mySharp" :disabled="formItemHook.myDisabled" :square="true" :halfHeight="true" @click="methods.reduce"><span class="fa fa-fw fa-caret-down"></span></a-button>
            </a-control-group>
        </template>
    </a-control-group>
</template>

<script setup lang="ts">
import AInputString from './AInputString.vue'
import AButton from './AButton.vue'
import AControlGroup from './AControlGroup.vue'
import { Decimal } from 'decimal.js'
import { InputPropsType, Rule_decimal, Rule_max, Rule_min } from '@/types'
import { computed, reactive } from 'vue'
import { useFormItem } from '@/hooks/useFormItem'
import { useInput } from '@/hooks/useInput'

interface PropsType extends InputPropsType<number | undefined, Rule_min | Rule_max | Rule_decimal> {
    step?: number
    clearable?: boolean
    placeholder?: string
    attachButtonShown?: boolean
    autoFocus?: boolean
}
const props = withDefaults(defineProps<PropsType>(), {
    value: undefined,
    color: undefined,
    disabled: undefined,
    size: undefined,
    sharp: undefined,
    rules: () => [],
    isInner: false,
    step: 1,
    clearable: true,
    placeholder: undefined,
    attachButtonShown: false,
    autoFocus: false,
})

interface StateType {
    inputStr?: string
}
const state = reactive<StateType>({
    inputStr: ''
})

const displayText = computed(() => {
    if (props.value === undefined) {
        return state.inputStr
    }
    return props.value.toString()
})

const emit = defineEmits<{
    (e: 'update:value', value?: number): void
    (e: 'focus'): void
    (e: 'blur'): void
}>()
useInput(props)
const formItemHook = useFormItem(props)

const methods = {
    input(val?: number) {
        emit('update:value', val)
    },
    add() {
        methods.input(new Decimal(props.value ?? 0).plus(new Decimal(props.step)).toNumber())
    },
    reduce() {
        methods.input(new Decimal(props.value ?? 0).minus(new Decimal(props.step)).toNumber())
    },
    onInput(val?: string) {
        state.inputStr = val
        let numVal: number | undefined = undefined
        if (val !== undefined && val !== '') {
            numVal = Number(val)
        }
        if (Number.isNaN(numVal)) {
            numVal = undefined
        }
        methods.input(numVal)
    },
}
</script>